package ru.niir.goodfil.ui;

import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;

import static java.lang.Thread.sleep;

public class EnviromentControlBean extends PageBean {
    private static final Logger logger = Logger.getLogger(EnviromentControlBean.class);

    private static final long START_MODULE_TIMEOUT = 3;

    private static final String LAST_1C_DATE_KEY = "events.last.1c";

    private static final String LAST_1C_DATE_DEFAULT = "никогда";

    private static final String LAST_BACKUP_DATE_KEY = "events.last.backup";

    private static final String LAST_BACKUP_DATE_DEFAULT = "никогда";

    private static final String ENV_NAMES_MAILER_KEY = ".env.names.mailer";

    private static final String START_MAILER_CMD_KEY = ".cmd.mailer.start";

    private static final String STOP_MAILER_CMD_KEY = ".cmd.mailer.stop";

    private static final String START_MAILER_CMD_DEFAULT = "/home/sazonov/scripts/mailer_start.sh";

    private static final String STOP_MAILER_CMD_DEFAULT = "/home/sazonov/scripts/mailer_stop.sh";

    private static final String START_BACKUPS_CMD_KEY = ".cmd.backups.start";

    private static final String STOP_BACKUPS_CMD_KEY = ".cmd.backups.stop";

    private static final String START_BACKUPS_CMD_DEFAULT = "/home/sazonov/scripts/backups_start.sh";

    private static final String STOP_BACKUPS_CMD_DEFAULT = "/home/sazonov/scripts/backups_stop.sh";

    private static final String START_1C_CMD_KEY = ".cmd.1c.start";

    private static final String STOP_1C_CMD_KEY = ".cmd.1c.stop";

    private static final String START_1C_CMD_DEFAULT = "/home/sazonov/scripts/c1_start.sh";

    private static final String STOP_1C_CMD_DEFAULT = "/home/sazonov/scripts/c1_stop.sh";

    private static final String STOP_H2_CMD_KEY = ".cmd.h2.stop";

    private static final String START_H2_CMD_KEY = ".cmd.h2.start";

    private static final String STOP_H2_CMD_DEFAULT = "/home/sazonov/scripts/h2_stop.sh";

    private static final String START_H2_CMD_DEFAULT = "/home/sazonov/scripts/h2_start.sh";

    private static final String ENV_NAMES_MAILER_DEFAULT = "/bin/sh ./GoodwillMailer.sh";

    private static final String ENV_NAMES_BACKUPS_KEY = ".env.names.backups";

    private static final String ENV_NAMES_BACKUPS_DEFAULT = "backup_goodwill_store_forever";

    private static final String ENV_NAMES_1C_KEY = ".env.names.1c";

    private static final String ENV_NAMES_1C_DEFAULT = "Goodwill1C.jar";

    private static final String ENV_NAMES_H2_KEY = ".env.names.h2";

    private static final String ENV_NAMES_H2_DEFAULT = "h2.tools.Server";

    private String last1CExchangeDate = null;

    private String lastBackupsDate = null;

    private Boolean mailerIsRunning = null;

    private Boolean backupsIsRunning = null;

    private Boolean c1IsRunning = null;

    public String getLast1CExchangeDate() {
        if (last1CExchangeDate == null) {
            gf().createIfNotExists(LAST_1C_DATE_KEY, LAST_1C_DATE_DEFAULT);
            last1CExchangeDate = gf().get(LAST_1C_DATE_KEY);
        }
        return last1CExchangeDate;
    }

    public String getLastBackupDate() {
        if (lastBackupsDate == null) {
            gf().createIfNotExists(LAST_BACKUP_DATE_KEY, LAST_BACKUP_DATE_DEFAULT);
            lastBackupsDate = gf().get(LAST_BACKUP_DATE_KEY);
        }
        return lastBackupsDate;
    }

    public boolean getMailerRunning() {
        if (mailerIsRunning == null) {
            gf().createIfNotExists(ENV_NAMES_MAILER_KEY, ENV_NAMES_MAILER_DEFAULT);
            String mailerName = gf().get(ENV_NAMES_MAILER_KEY);
            try {
                boolean result = ru.niir.goodfil.ui.utils.Process.exists(mailerName);
                logger.debug(result ? "Mailer is running" : "Mailer is NOT running");
                mailerIsRunning = result;
            } catch (Exception e) {
                facesError("Не удается получит информацию о состоянии модуля \"Робота рассылки\"");
                mailerIsRunning = false;
            }
        }
        return mailerIsRunning;
    }

    public boolean getBackupsRunning() {
        if (backupsIsRunning == null) {
            gf().createIfNotExists(ENV_NAMES_BACKUPS_KEY, ENV_NAMES_BACKUPS_DEFAULT);
            String backupsName = gf().get(ENV_NAMES_BACKUPS_KEY);
            try {
                boolean result = ru.niir.goodfil.ui.utils.Process.exists(backupsName);
                logger.debug(result ? "Backups is running" : "Backups is NOT running");
                backupsIsRunning = result;
            } catch (Exception e) {
                facesError("Не удается получить информацию о состоянии модуля \"Архиватор\"");
                backupsIsRunning = false;
            }
        }
        return backupsIsRunning;
    }

    public boolean getC1Running() {
        if (c1IsRunning == null) {
            gf().createIfNotExists(ENV_NAMES_1C_KEY, ENV_NAMES_1C_DEFAULT);
            String c1Name = gf().get(ENV_NAMES_1C_KEY);
            try {
                boolean result = ru.niir.goodfil.ui.utils.Process.exists(c1Name);
                logger.debug(result ? "1C is running" : "1C is NOT running");
                c1IsRunning = result;
            } catch (Exception e) {
                facesError("Не удается получить информацию о состоянии модуля \"Интеграция с 1С\"");
                c1IsRunning = false;
            }
        }
        return c1IsRunning;
    }

    public boolean getH2Running() throws IOException, InterruptedException {
        String h2Name = gf().getOrCreateIfNotExists(ENV_NAMES_H2_KEY, ENV_NAMES_H2_DEFAULT, "Подстрока в ps ax по которой можно судить о H2");
        boolean result = ru.niir.goodfil.ui.utils.Process.exists(h2Name);
        logger.debug(result ? "H2 is running" : "H2 is NOT running");
        return result;
    }

    private void startModule(String cmd, long waitTimeout) throws IOException, InterruptedException {
        Runtime.getRuntime().exec(cmd);
        sleep(waitTimeout);

        c1IsRunning = null;
        mailerIsRunning = null;
        backupsIsRunning = null;
        last1CExchangeDate = null;
        lastBackupsDate = null;
    }


    public void startH2() throws InterruptedException {
        try {
            String cmd = gf().getOrCreateIfNotExists(START_H2_CMD_KEY, START_H2_CMD_DEFAULT, "Команда для запуска БД H2");
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось запустить базу H2");
        }
    }

    public void stopH2() throws InterruptedException {
        try {
            String cmd = gf().getOrCreateIfNotExists(STOP_H2_CMD_KEY, STOP_H2_CMD_DEFAULT, "Команда для остановки БД H2");
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось остановить базу H2");
        }
    }

    public void backupH2() {
        try {
            if (getH2Running()) {
                stopH2();
            }
            Thread.sleep(START_MODULE_TIMEOUT);

            String timestamp = new SimpleDateFormat("yyyyMMdd_HHmm").format(Calendar.getInstance().getTime());
            String dir = gf().getOrCreateIfNotExists(".h2.database.copy", "/home/sazonov/h2/h2/bin/home/sazonov", "Каталог, из которого следует скопировать БД H2");
            FileUtils.copyFile(new File(dir + File.separator + "GoodwillAudit.h2.db"),
                    new File(dir + File.separator + "GoodwillAudit.h2.db_" + timestamp));

            FileUtils.deleteQuietly(new File(dir + File.separator + "GoodwillAudit.h2.db"));

            if (!getH2Running()) {
                startH2();
            }
            Thread.sleep(START_MODULE_TIMEOUT);

        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось сделать бэкап H2");
        }
    }

    public void startMailer() throws InterruptedException {
        try {
            gf().createIfNotExists(START_MAILER_CMD_KEY, START_MAILER_CMD_DEFAULT);
            String cmd = gf().get(START_MAILER_CMD_KEY);
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось запустить модуль \"Робот рассылки\"");
        }
    }

    public void stopMailer() throws InterruptedException {
        try {
            gf().createIfNotExists(STOP_MAILER_CMD_KEY, STOP_MAILER_CMD_DEFAULT);
            String cmd = gf().get(STOP_MAILER_CMD_KEY);
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось остановить модуль \"Робот рассылки\"");
        }
    }

    public void startBackups() throws InterruptedException {
        try {
            gf().createIfNotExists(START_BACKUPS_CMD_KEY, START_BACKUPS_CMD_DEFAULT);
            String cmd = gf().get(START_BACKUPS_CMD_KEY);
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось запустить модуль \"Архиватор\"");
        }
    }

    public void stopBackups() throws InterruptedException {
        try {
            gf().createIfNotExists(STOP_BACKUPS_CMD_KEY, STOP_BACKUPS_CMD_DEFAULT);
            String cmd = gf().get(STOP_BACKUPS_CMD_KEY);
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось остановить модуль \"Архиватор\"");
        }
    }

    public void startC1() throws InterruptedException {
        try {
            gf().createIfNotExists(START_1C_CMD_KEY, START_1C_CMD_DEFAULT);
            String cmd = gf().get(START_1C_CMD_KEY);
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось запустить модуль \"Интеграция с 1С\"");
        }
    }

    public void stopC1() throws InterruptedException {
        try {
            gf().createIfNotExists(STOP_1C_CMD_KEY, STOP_1C_CMD_DEFAULT);
            String cmd = gf().get(STOP_1C_CMD_KEY);
            startModule(cmd, 1000 * START_MODULE_TIMEOUT);
        } catch (Exception e) {
            e.printStackTrace();
            facesError("Не удалось остановить модуль \"Интеграция с 1С\"");
        }
    }
}
